package com.gaoyi.crm.util;


import android.text.TextUtils;

import com.gaoyi.crm.apiresult.ApiResultData;
import com.gaoyi.crm.callback.OnResultListener;
import com.gaoyi.crm.callback.OnSyncListener;
import com.gaoyi.crm.constant.ApiStatus;
import com.gaoyi.crm.db.dto.SyncResultDto;
import com.gaoyi.crm.db.entity.PmnAttach;
import com.gaoyi.crm.db.entity.PmnWithList;
import com.gaoyi.crm.repository.PmnAttachRepository;
import com.gaoyi.crm.repository.PmnRepository;
import com.gaoyi.crm.repository.SyncRepository;
import com.gaoyi.crm.repository.UtilRepository;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class SyncUploadUtil {
    private static volatile SyncUploadUtil INSTANCE;

    final PmnRepository mPmn;
    final UtilRepository mUtil;
    final SyncRepository mSync;
    OnSyncListener mListener;
    final PmnAttachRepository mPmnAttach;

    public static SyncUploadUtil getInstance() {
        if (INSTANCE == null) {
            synchronized (SyncUploadUtil.class) {
                if (INSTANCE == null) {
                    INSTANCE = new SyncUploadUtil();
                }
            }
        }
        return INSTANCE;
    }


    public SyncUploadUtil() {
        mPmn = new PmnRepository();
        mUtil = new UtilRepository();
        mSync = new SyncRepository();
        mPmnAttach = new PmnAttachRepository();
    }

    public void syncPmn(List<PmnWithList> pmns, OnSyncListener onResultListener) {
        mListener = onResultListener;
        ergodicAttach(pmns, 0);
    }

    /**
     * 遍历每个Pmn里面的PmnAttach
     *
     * @param position 当前位置
     */
    private void ergodicAttach(List<PmnWithList> pmns, int position) {
        if (pmns.size() == position) {// 全部上传完成，开始同步
            uploadPmn(pmns);
            return;
        }
        PmnWithList pmn = pmns.get(position);
        List<PmnAttach> pmnAttaches = pmn.pmnAttachs;
        if (pmnAttaches != null && !pmnAttaches.isEmpty()) {
            uploadPhoto(pmns, pmnAttaches, 0, position);
            return;
        }
        ergodicAttach(pmns, position + 1);
    }

    /**
     * 上传图片
     *
     * @param pmnAttaches 图片组
     * @param position    当前遍历Attach的位置
     * @param pmnPosition 当前遍历Pmn的位置
     */
    private void uploadPhoto(List<PmnWithList> pmns, List<PmnAttach> pmnAttaches, int position, int pmnPosition) {
        if (pmnAttaches.size() == position) { // 当前Pmn的Attach全部上传完成，遍历下一个Pmn
            pmns.get(pmnPosition).pmnAttachs = pmnAttaches;
            ergodicAttach(pmns, pmnPosition + 1);
            return;
        }
        String uploadPath = pmnAttaches.get(position).getUploadPath();
        if (!TextUtils.isEmpty(uploadPath)) { // 文件已上传
            pmnAttaches.get(position).setAttach(uploadPath); // 修改上传文件的名称为服务器地址名称
            uploadPhoto(pmns, pmnAttaches, position + 1, pmnPosition); // 继续遍历上传文件
            return;
        }
        String attach = pmnAttaches.get(position).getAttach();
        mUtil.upload(attach, new OnResultListener() {
            @Override
            public void onSuccess(Object apiResult) {
                ApiResultData<String> apiResultData = (ApiResultData<String>) apiResult;
                if (apiResultData.getStatus() != ApiStatus.SUCCESS) {
                    String content = pmns.get(pmnPosition).pmn.getCode() + "-Images：" + attach.substring(attach.lastIndexOf("/") + 1) + "-" + apiResultData.getMessage();
                    mListener.onError(content);
                    return;
                }
                String path = apiResultData.getData();
                pmnAttaches.get(position).setAttach(path); // 修改上传文件的名称为服务器地址名称
                uploadPhoto(pmns, pmnAttaches, position + 1, pmnPosition); // 继续遍历上传文件
                mPmnAttach.updateUploadPath(pmnAttaches.get(position).getId(), path); // 修改本地上传文件的路径，标识当前文件已上传，避免重复上传
            }

            @Override
            public void onFails(Exception e) {
                mListener.onFails(e);
            }
        }, new TypeToken<ApiResultData<String>>() {
        }.getType());
    }

    /**
     * 同步上传Pmn
     */
    private void uploadPmn(List<PmnWithList> pmns) {
        mSync.syncUpload(pmns, new OnResultListener() {
            @Override
            public void onSuccess(Object apiResult) {
                ApiResultData<SyncResultDto> apiResultData = (ApiResultData<SyncResultDto>) apiResult;
                if (apiResultData.getStatus() != ApiStatus.SUCCESS) {
                    mListener.onError(apiResultData.getMessage());
                    return;
                }
                SyncResultDto data = apiResultData.getData();
                if (data == null) {
                    // 上传成功并且没有返回参数后将全部Pmn状态改成Synced
                    updatePmnSync(pmns);
                    return;
                }
                String duplCode = "";
                List<String> duplCodes = data.getDuplCodes();
                if (duplCodes != null && !duplCodes.isEmpty()) { // 有上传失败的Pmn
                    StringBuilder codes = new StringBuilder();
                    for (String code : duplCodes) {
                        codes.append(",").append(code);
                    }
                    duplCode = codes.substring(1);
                }
                updatePmnSyncByIds(data.getSuccIds(),duplCode); // 修改上传成功的同步状态
            }

            @Override
            public void onFails(Exception e) {
                mListener.onFails(e);
            }
        }, new TypeToken<ApiResultData<SyncResultDto>>() {
        }.getType());
    }

    private void updatePmnSyncByIds(List<String> ids,String duplCode) {
        if (ids == null || ids.isEmpty()) {
            callback(duplCode);
            return;
        }
        mPmn.updatePmnSync(ids, new Date(), ApiStatus.SYNC_SUCCESS, new OnResultListener() {
            @Override
            public void onSuccess(Object apiResult) {
                callback(duplCode);
            }

            @Override
            public void onFails(Exception e) {

            }
        });
    }

    private void callback(String duplCode) {
        if (TextUtils.isEmpty(duplCode)) {
            mListener.onSuccess();
        }else {
            mListener.onError(duplCode);
        }
    }

    /**
     * 修改Pmn同步状态和时间
     *
     * @param pmns
     */
    private void updatePmnSync(List<PmnWithList> pmns) {
        List<String> ids = new ArrayList<>();
        for (PmnWithList pmn : pmns) {
            ids.add(pmn.pmn.getId());
        }
        updatePmnSyncByIds(ids,"");
    }

}
